package me.evis.mobile.sms2cal.parser;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

import me.evis.mobile.sms2cal.model.CalEvent;
import me.evis.mobile.sms2cal.model.SmsData;
import android.util.Log;

public class GenericCanonicalSmsParser implements SmsParser {
    /** Tag string for debug logs */
    private static final String TAG = "me.evis.mobile.sms2cal.parser.GenericCanonicalSmsParser";
    
    private List<CompiledCanonicalParseRule> parseRules = new ArrayList<CompiledCanonicalParseRule>();

    public GenericCanonicalSmsParser() {
        initRules();
    }
    
    public GenericCanonicalSmsParser(List<CanonicalParseRule> rules) {
        for (CanonicalParseRule rule : rules) {
            parseRules.add(new CompiledCanonicalParseRule(rule));
        }
    }
    
    @Override
    public boolean parse(SmsData sms, List<CalEvent> results) {
        for (CompiledCanonicalParseRule rule : parseRules) {
            if (internalParse(sms, rule, results)) {
                return true;
            }
        }
        
        return false;
    }
    
    private boolean internalParse(SmsData sms, CompiledCanonicalParseRule rule, List<CalEvent> results) {
        // Is parser applicable
        boolean applicable = false;
        if (rule.possibleSenders.contains(sms.from)) {
            Matcher m = rule.matchPattern.matcher(sms.messageBody);
            if (m.matches()) {
                applicable = true;
            }
        }
        if (!applicable) {
            return false;
        }
        
        // Parse
        Map<String, String> values = new HashMap<String, String>();
        for (CompiledCanonicalParseRule.CompiledParsePattern pattern : rule.parsePatterns) {
            Matcher m = pattern.pattern.matcher(sms.messageBody);
            if (m.find()) {
                for (Integer index : pattern.matchGroupLabels.keySet()) {
                    String key = pattern.matchGroupLabels.get(index);
                    int groupIndex = (index < 0) ? (m.groupCount() + 1 + index) : index;
                    String value = m.group(groupIndex);
                    values.put(key, value);
                }
            }
        }
        
        Log.d(TAG, values.toString());
        
        try {
            results.add(rule.calEventTemplate.toCalEvent(values));
        } catch (ParseException e) {
            Log.d(TAG, "Error applying CalEvent template e: " + e);
        }
        
        return true;
    }
    
    protected void initRules() {
        // TODO
    }
}
